Shell 语法进阶:特殊符号与正则表达式
前半侧重交互式串联与引号;后半区分 文件名通配 与 文本模式匹配。
一、命令之间的逻辑关系
shell
cmd1 ; cmd2 # 顺序执行,互不影响
cmd1 && cmd2 # cmd1 成功才执行 cmd2
cmd1 || cmd2 # cmd1 失败才执行 cmd2示例:ls ; cd /etc/ ; ls -a、ls && cd /etc/ 等。
二、文件名通配符(Glob)
用于匹配路径名字符串(不少命令里未开启正则,用的是 glob):
| 符号 | 含义 |
|---|---|
? | 单个任意字符 |
* | 零个或多个任意字符 |
[abc] | 括号内任一字符 |
[a-z] | 范围内任一字符 |
[^0-9] | 排除括号内所列 |
三、引号与替换
| 符号 | 含义 |
|---|---|
'' | 单引号:强引用,内容多为字面量 |
"" | 双引号:可展开变量、$( )、部分转义 |
` | 反引号:命令替换(旧写法,易与引号嵌套混淆) |
$( ) | 命令替换(推荐) |
$(( )) | 算术展开 |
# | 行注释 |
$ | 变量引用 |
四、子 Shell:() 与 {}
( commands ):在子 Shell 中执行,变量等改动不影响当前 Shell。{ commands; }:在当前 Shell 执行;多条命令用;分隔,最后一个命令后、}前也要有分号(与( )不同);{与首个命令之间必须有空格。
区别简述
()会启动子 Shell;{}不启动。()里多条命令用;分隔,最后一条可不加分号(仍建议统一加);{}内通常最后也需;。- 内外层重定向作用范围不同:块外的重定向作用于块内全部命令。
五、父 Shell 与子 Shell
在终端里输入 bash 可进入子 Shell,exit 返回;pstree 可观察进程树。脚本里 (...) 同理。
六、测试:[ ] 与 [[ ]]
[ ] 常与 test 等价;[[ ]] 是 Bash 关键字,支持更多模式匹配。变量测试时注意引号,例如 [ "$name" = "张三" ]。
七、正则表达式与通配符的区别
- 正则:在文本内容里找模式;常用于
grep、sed、awk(按具体选项与方言)。 - 通配符(glob):多用在文件名匹配;
ls、cp等按路径展开规律不是正则。 find -name:后跟的是 glob 风格 的图案,不是扩展正则。
勿把 grep 里的 *(「前一个元素重复」)与文件名里的 * 混为一谈。
八、find 中的通配(按文件名找)
shell
find . -name "abc*" # 以 abc 开头
find . -name "a?c" # a + 一字 + c
# [] [^] 等同理九、grep 与基本正则 / 扩展正则(示例)
在 grep 默认基本正则(BRE) 语境下(部分模式需转义):
| 模式 | 含义 |
|---|---|
* | 前一个字符重复 0 次或多次 |
? | (BRE 中常需写成 \?)前一个字符 0 或 1 次 |
[] | 括号内任一字符 |
^ / $ | 行首 / 行尾 |
\{n\} 等 | 重复次数 |
shell
grep "abc*" file1
grep '^abc' file1扩展正则(ERE) 常用 grep -E:
+:一次或多次?:0 或 1 次|:分支():分组
实际使用时务必加 grep 手册 或 grep -E / egrep 说明,因为 GNU 与 BSD 选项略有差异。
十、小结
- 先分清场景:是匹配文件名(glob / find -name)还是匹配日志内容(grep/sed/awk 正则)。
- Bash 参数展开
${var/pattern/}等属于 Shell 语法,与正则不是同一套规则。 - 复杂匹配优先在
grep -E、perl -ne或rg(ripgrep)里完成,可读性往往更好。
